﻿using System;
using System.Collections;
using System.Text;
using System.Data;
using GeneralLibs;
using System.Data.SqlClient;

namespace Lists
{
    public class NhapXuatTon : DoiTuong
    {
        #region Guid VatTuHangHoaID property
        public Guid VatTuHangHoaID
        {
            get
            {
                if (_DataRow["VatTuHangHoaID"] is Guid) return (Guid)_DataRow["VatTuHangHoaID"];
                return Guid.Empty;
            }
            set
            {
                _DataRow["VatTuHangHoaID"] = value;
            }
        }
        #endregion

        #region Guid KhoID property
        public Guid KhoID
        {
            get
            {
                if (_DataRow["KhoID"] is Guid) return (Guid)_DataRow["KhoID"];
                return Guid.Empty;
            }
            set
            {
                _DataRow["KhoID"] = value;
            }
        }
        #endregion

        #region decimal TonDauKy property
        public decimal TonDauKy
        {
            get
            {
                if (_DataRow["TonDauKy"] is decimal) return (decimal)_DataRow["TonDauKy"];
                return 0;
            }
            set
            {
                _DataRow["TonDauKy"] = value;
            }
        }
        #endregion


        #region decimal SoLuongNhap property
        public decimal SoLuongNhap
        {
            get
            {
                if (_DataRow["SoLuongNhap"] is decimal) return (decimal)_DataRow["SoLuongNhap"];
                return 0;
            }
            set
            {
                _DataRow["SoLuongNhap"] = value;
            }
        }
        #endregion

        #region decimal SoLuongXuat property
        public decimal SoLuongXuat
        {
            get
            {
                if (_DataRow["SoLuongXuat"] is decimal) return (decimal)_DataRow["SoLuongXuat"];
                return 0;
            }
            set
            {
                _DataRow["SoLuongXuat"] = value;
            }
        }
        #endregion

        #region decimal SoLuongTon property
        public decimal SoLuongTon
        {
            get
            {
                if (_DataRow["SoLuongTon"] is decimal) return (decimal)_DataRow["SoLuongTon"];
                return 0;
            }
            set
            {
                _DataRow["SoLuongTon"] = value;
            }
        }
        #endregion

        #region decimal DonGiaTon property
        public decimal DonGiaTon
        {
            get
            {
                if (_DataRow["DonGiaTon"] is decimal) return (decimal)_DataRow["DonGiaTon"];
                return 0;
            }
            set
            {
                _DataRow["DonGiaTon"] = value;
            }
        }
        #endregion

        #region decimal ThanhTienTon property
        public decimal ThanhTienTon
        {
            get
            {
                if (_DataRow["ThanhTienTon"] is decimal) return (decimal)_DataRow["ThanhTienTon"];
                return 0;
            }
            set
            {
                _DataRow["ThanhTienTon"] = value;
            }
        }
        #endregion

        public NhapXuatTon(DataRow dataRow)
            : base(dataRow)
        {
        }
    }

    public class DanhMucNhapXuatTon : DanhMucDoiTuong, IEnumerable
    {
        #region Instance property: Singleton Design pattern
        private static DanhMucNhapXuatTon _Instance;
        public static DanhMucNhapXuatTon Instance
        {
            get
            {
                if (_Instance == null)
                {
                    _Instance = new DanhMucNhapXuatTon();
                    _Instance.DataView = _Instance.DataTable.DefaultView;
                }
                return _Instance;
            }
        }
        #endregion

        #region override TableName property
        public override string TableName
        {
            get
            {
                return "NhapXuatTon";
            }
        }
        #endregion

        #region Methods required by IEnumerable (use for foreach)
        public IEnumerator GetEnumerator()
        {
            return new TokenEnumerator(this);
        }

        private class TokenEnumerator : IEnumerator
        {
            private int _Position = -1;
            DanhMucDoiTuong _Dstk;

            public TokenEnumerator(DanhMucDoiTuong dstk)
            {
                _Dstk = dstk;
            }

            // Declare the MoveNext method required by IEnumerator:
            public bool MoveNext()
            {
                if (_Position < _Dstk.DataView.Count - 1)
                {
                    _Position++;
                    return true;
                }
                else
                {
                    return false;
                }
            }

            // Declare the Reset method required by IEnumerator:
            public void Reset()
            {
                _Position = -1;
            }

            // Declare the Current property required by IEnumerator:
            public object Current
            {
                get
                {
                    return new NhapXuatTon((_Dstk.DataView[_Position].Row));
                }
            }
        }
        #endregion

        public NhapXuatTon this[int index]
        {
            get
            {
                if (0 <= index && index <= this.Count)
                {
                    return new NhapXuatTon(DataTable.Rows[index]);
                }
                else
                {
                    return null;
                }
            }
        }

        public NhapXuatTon NewDoiTuong()
        {
            try
            {
                return new NhapXuatTon(Instance.DataTable.NewRow());
            }
            catch (Exception ex)
            {
                if (ex is CustomException) throw ex;
                else
                {
                    throw new Exception(ex.Message);
                }
            }
        }

        public NhapXuatTon GetByProperty(string property, object value)
        {
            try
            {
                DataRow[] rows = GetDataRows(property, value);
                if (rows.Length > 0) return new NhapXuatTon(rows[0]);
                else return null;
            }
            catch (Exception ex)
            {
                if (ex is CustomException) throw ex;
                else
                {
                    throw new Exception(ex.Message);
                }
            }
        }

        public NhapXuatTon GetByID(Guid objID)
        {
            try
            {
                return GetByProperty("ID", objID);
            }
            catch (Exception ex)
            {
                if (ex is CustomException) throw ex;
                else
                {
                    throw new Exception(ex.Message);
                }
            }
        }

        public static DanhMucNhapXuatTon GetAll()
        {
            try
            {
                return Instance;
            }
            catch (Exception ex)
            {
                if (ex is CustomException) throw ex;
                else
                {
                    throw new Exception(ex.Message);
                }
            }
        }

        public NhapXuatTon GetByVatTuHangHoaIDAndKhoID(Guid vthhID, Guid khoID)
        {
            DanhMucNhapXuatTon dm = Filter(string.Format("VatTuHangHoaID = '{0}' AND KhoID = '{1}'", vthhID, khoID));
            if (dm.DataView != null && dm.DataView.Count == 1)
                return new NhapXuatTon(dm.DataView[0].Row);
            else return null;
        }
        public NhapXuatTon GetByVatTuHangHoaID(Guid vthhID)
        {
            DanhMucNhapXuatTon dm = Filter(string.Format("VatTuHangHoaID = '{0}'", vthhID));

            ThoiDiemKhoaSo thoiDiemKhoaSoGanNhat = DanhMucThoiDiemKhoaSo.Instance.GetThoiDiemKhoaSoGanNhat(DateTime.Now);
            if (dm.DataView.Count <= 0) return null;
            NhapXuatTon result = new NhapXuatTon(dm.DataView[0].Row);
            if (result != null)
            {
                result.DonGiaTon = (decimal)DanhMucVatTuHangHoa.Instance.GetGiaVonTrungBinhTheoGiaTriConLaiToanBoCacKhoByID(vthhID,
                                    thoiDiemKhoaSoGanNhat.ID, thoiDiemKhoaSoGanNhat.ThoiDiem, DateTime.Now);
                result.KhoID = Guid.Empty;

                foreach (NhapXuatTon item in dm)
                {
                    result.TonDauKy += item.TonDauKy;
                    result.SoLuongNhap += item.SoLuongNhap;
                    result.SoLuongXuat += item.SoLuongXuat;
                    result.SoLuongTon += item.SoLuongTon;
                }
                result.ThanhTienTon = result.DonGiaTon * result.SoLuongTon;
            }

            return result;
        }

        public static DanhMucNhapXuatTon Filter(string filterExpression)
        {
            try
            {
                DanhMucNhapXuatTon obj = new DanhMucNhapXuatTon();
                obj.DataView = new DataView(DanhMucNhapXuatTon.Instance.DataTable, filterExpression, "", DataViewRowState.CurrentRows);
                return obj;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        public DataTable GetTonKhoNhanhByKhoID(Guid khoID, string vthhCondition, int tonKhoMin, int tonKhoMax)
        {
            SqlConnection con = new SqlConnection(GeneralLibs.LocalSettings.ConnectString);
            try
            {
                con.Open();
                SqlCommand cmd = con.CreateCommand(); cmd.CommandTimeout = Config.TimeOut;
                cmd.CommandText = string.Format("SELECT B.Ma, B.Ten, B.GiaBia, A.TonDauKy TonDau, A.SoLuongNhap, A.SoLuongXuat, \n" +
                                "		(A.TonDauKy + A.SoLuongNhap - A.SoLuongXuat) SoLuongTon, DonGiaTon DonGiaVon, \n" +
                                "       ((A.TonDauKy + A.SoLuongNhap - A.SoLuongXuat) * DonGiaTon) ThanhTienVon \n" +
                                "FROM NhapXuatTon A INNER JOIN VatTuHangHoa B ON A.VatTuHangHoaID = B.ID \n" +
                                "WHERE (TonDauKy <> 0 OR SoLuongNhap <>0 OR SoLuongXuat <> 0 OR SoLuongTon <> 0) \n" +
                                "       AND {0} <= SoLuongTon AND SoLuongTon <= {1} \n" +
                                "       AND {2} \n" +
                                "       AND A.KhoID = '{3}'",
                                tonKhoMin, tonKhoMax, vthhCondition, khoID);
                SqlDataAdapter da = new SqlDataAdapter();
                DataTable dt = new DataTable();
                da.SelectCommand = cmd;
                da.Fill(dt);
                return dt;
            }
            catch (Exception ex)
            {
                throw ex;
                return null;
            }
        }
        public DataTable GetTonKhoNhanhToanBoCacKho(string vthhCondition, int tonKhoMin, int tonKhoMax)
        {
            SqlConnection con = new SqlConnection(GeneralLibs.LocalSettings.ConnectString);
            try
            {
                con.Open();
                SqlCommand cmd = con.CreateCommand(); cmd.CommandTimeout = Config.TimeOut;
                cmd.CommandText = string.Format("SELECT B.Ma, B.Ten, B.GiaBia, SUM(A.TonDauKy) TonDau, SUM(A.SoLuongNhap) SoLuongNhap, SUM(A.SoLuongXuat) SoLuongXuat, \n" +
                                "		SUM(A.TonDauKy + A.SoLuongNhap - A.SoLuongXuat) SoLuongTon, SUM(DonGiaTon) DonGiaVon,  \n" +
                                "       SUM((A.TonDauKy + A.SoLuongNhap - A.SoLuongXuat) * DonGiaTon) ThanhTienVon \n" +
                                "FROM NhapXuatTon A INNER JOIN VatTuHangHoa B ON A.VatTuHangHoaID = B.ID \n" +
                                "WHERE (TonDauKy <> 0 OR SoLuongNhap <>0 OR SoLuongXuat <> 0 OR SoLuongTon <> 0) \n" +
                                "       AND {0} <= SoLuongTon AND SoLuongTon <= {1} \n" +
                                "       AND {2} \n" +
                                "GROUP BY A.KhoID, B.Ma, B.Ten, B.GiaBia",
                                tonKhoMin, tonKhoMax, vthhCondition);
                SqlDataAdapter da = new SqlDataAdapter();
                DataTable dt = new DataTable();
                da.SelectCommand = cmd;
                da.Fill(dt);
                return dt;
            }
            catch (Exception ex)
            {
                throw ex;
                return null;
            }
        }

        public decimal GetGiaTriHangTonKho()
        {
            SqlConnection con = new SqlConnection(GeneralLibs.LocalSettings.ConnectString);
            try
            {
                con.Open();
                SqlCommand cmd = con.CreateCommand(); cmd.CommandTimeout = Config.TimeOut;
                cmd.CommandText = string.Format("SELECT SUM (ThanhTienTon) ThanhTien FROM NhapXuatTon \n" +
                                "WHERE (TonDauKy <> 0 OR SoLuongNhap <>0 OR SoLuongXuat <> 0 OR SoLuongTon <> 0) \n" +
                                "AND VatTuHangHoaID IN ( \n" +
                                "SELECT ID FROM VatTuHangHoa WHERE TrangThai = 1 or TrangThai is null )");
                SqlDataReader dr = cmd.ExecuteReader();
                if (dr.Read() && dr["ThanhTien"] != DBNull.Value)
                    return (decimal)dr["ThanhTien"];
                else
                    return 0;
                dr.Close();
            }
            catch (Exception ex)
            {
                throw ex;
                return 0;
            }
        }
    }
}
